package eu.jba.denshijisho;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.MenuItemCompat;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;
import android.widget.Toast;
import eu.jba.denshijisho.adapter.CardAdapter;
import eu.jba.denshijisho.algorithm.Algorithm;
import eu.jba.denshijisho.dao.CardDao;
import eu.jba.denshijisho.dao.StatDao;
import eu.jba.denshijisho.entity.Card;
import eu.jba.denshijisho.entity.Stat;
import eu.jba.denshijisho.exceptionhandler.ExceptionHandler;
import eu.jba.denshijisho.listeners.ListenersHelper;
import eu.jba.denshijisho.util.Constants;
import eu.jba.denshijisho.util.DataProvider;
import eu.jba.denshijisho.util.DataProviderImpl;
import eu.jba.denshijisho.util.Util;
import eu.jba.denshijisho.util.Util.ExportHolder;

public class DatabaseActivity extends AbstractDenshiActivity {

	private Boolean doubleBackToExitPressdOnce = false;
	private Boolean showWords = true;
	private Boolean showPhrases = true;
	
	private List<Card> quizQuestions;
	private List<Card> cardsList;
	private Integer index = 0;
	private Integer rightAnswer = 0;
	private Integer wrongAnswer = 0;
	private DataProvider dataProvider;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Thread.setDefaultUncaughtExceptionHandler( new ExceptionHandler( this ));
		Util.lockScreenOrientation( this );
		setContentView(R.layout.activity_database);
	
		final CardDao cardDao = new CardDao(this);
		cardDao.open();

		final ListView lv = (ListView) findViewById(R.id.card_list_view_main);
		lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
		lv.setOnItemClickListener( ListenersHelper.getListViewItemListener() );

		final CardAdapter arrayAdapter = getAdapter(cardDao);
		lv.setAdapter(arrayAdapter);
		registerForContextMenu(lv);
		cardDao.close();
	}
	
	@Override
	protected void onDestroy() {
		Util.unlockScreenOrientation(this);
		super.onDestroy();
	}

	@Override
	public boolean onCreateOptionsMenu(final Menu menu) {
		super.onCreateOptionsMenu(menu);
		getMenuInflater().inflate(R.menu.main_action_menu, menu);
		final SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
		final MenuItem menuItem = menu.findItem(R.id.search);
		final SearchView search = (SearchView) menuItem.getActionView();
		search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));
		search.setOnQueryTextListener(new OnQueryTextListener() {

			@Override
			public boolean onQueryTextChange(String newText) {
				return false;
			}

			@Override
			public boolean onQueryTextSubmit(String query) {
				final List<Card> filteredCards = filterElements(query);
				final ListView lv = (ListView) findViewById(R.id.card_list_view_main);
				final CardAdapter arrayAdapter = new CardAdapter(
						DatabaseActivity.this, R.layout.listview_item_row,
						filteredCards);
				lv.setAdapter(arrayAdapter);
				search.clearFocus();
				search.setQuery("", false);
				search.setFocusable(false);
				MenuItemCompat.collapseActionView(menuItem);
				return true;
			}
		});
		return true;
	}

	private List<Card> filterElements(String query) {
		final CardDao cardDao = new CardDao( this );
		cardDao.open();
		final List<Card> result = cardDao.search(query);
		return result;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.newCard) {
			setReloadData( true );
			startActivityForResult(new Intent(this, CreateNewActivity.class), 1);
		}
		if (item.getItemId() == R.id.reload) {
			setReloadData( true );
			updateListView();
		}
		if (item.getItemId() == R.id.export) {
			final CardDao cardDao = new CardDao(this);
			cardDao.open();
			final List<Card> cards = cardDao.getAll();
			cardDao.close();
			Util.exportDB(this, new ExportHolder<Card>(cards) {

				@Override
				public String[] convertToStringData(Card row) {
					final StatDao statDao = new StatDao( DatabaseActivity.this );
					statDao.open();
					row.setStat( statDao.get( row.getStatId() ) );
					statDao.close();
					return new String[] { row.getId().toString(),
							row.getSvkWord(), row.getKanaWord(),
							row.getKanji(), row.getType(),
							row.getStat().getId().toString() };
				}

				@Override
				public String[] getColumnNames() {
					return CardDao.getColumnNames();
				}
			}, this.getString(R.database.CARD_TABLE));
			final StatDao statDao = new StatDao(this);
			statDao.open();
			final List<Stat> stats = statDao.getAll();
			statDao.close();
			Util.exportDB(this, new ExportHolder<Stat>(stats) {

				@Override
				public String[] convertToStringData(Stat row) {
					return new String[] { row.getId().toString(),
							Util.dateToString(row.getNextDate()),
							Util.dateToString(row.getPreviousDate()),
							row.getInterval().toString(),
							row.getReps().toString(),
							row.getOkAnswers().toString(),
							row.getWrongAnswers().toString(),
							row.getEf().toString() };
				}

				@Override
				public String[] getColumnNames() {
					return StatDao.getColumnNames();
				}
			}, this.getString(R.database.STAT_TABLE));
		}
		if (item.getItemId() == R.id.importData) {
			Util.getUnsupportedOperation(this);
		}
		if (item.getItemId() == R.id.quiz) {
			dataProvider = new DataProviderImpl(this);
			quizQuestions = dataProvider.provideData();
			showNext();
		}
		if(item.getItemId() == R.id.preferences){
			startActivity( new Intent(this, SettingsActivity.class));
		}
		if(item.getItemId() == R.id.overallStats){
			startActivity(new Intent(this, OverallStatActivity.class));
		}
		if( (item.getItemId() == R.id.show_words)){
			if( item.isChecked() ){
				item.setChecked( false );
				showWords = false;
			}else{
				item.setChecked( true );
				showWords = true;
			}
			setReloadData( true );
			updateListView();
		}

		if( (item.getItemId() == R.id.show_phrases)){
			if( item.isChecked() ){
				item.setChecked( false );
				showPhrases = false;
			}else{
				item.setChecked( true );
				showPhrases = true;
			}
			setReloadData( true );
			updateListView();
		}

		return super.onOptionsItemSelected(item);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == RESULT_OK) {
			setReloadData( true );
			updateListView();
		}
		if( resultCode == Constants.RESULT_KNOW){
			updateStat(5);
			rightAnswer++;
			nextQuestion();
		}
		if( resultCode == Constants.RESULT_DONT_KNOW ){
			updateStat(1);
			wrongAnswer++;
			nextQuestion();
		}
	}

	private void nextQuestion(){
		if( quizQuestions.size() > index ){
			showNext();
		}else{
			dataProvider.writeData( quizQuestions );
			showStat();
		}
	}
	
	private void updateStat( int grade ){
		final Card card = quizQuestions.get( index -1 );
		Algorithm.calcIntervalEF(card, grade);
	}
	
	private void showStat(){
		Toast.makeText(
			this, 
			"Total: " + (rightAnswer + wrongAnswer) + ", Right: " + rightAnswer + ", Wrong: " + wrongAnswer, 
			Toast.LENGTH_LONG
		).show();
		index = 0;
		rightAnswer = 0;
		wrongAnswer = 0;
	}
	
	private Stat getStat(int id){
		final StatDao statDao = new StatDao(this);
		statDao.open();
		final Stat stat = statDao.get( id );
		statDao.close();
		return stat;
	}
	
	private void showNext(){
		final Intent quizQuestionIntent = new Intent( this, QuestionDisplayerActivity.class);
		final Card card = quizQuestions.get( index );
		card.setStat( getStat( card.getStatId() ));
		quizQuestionIntent.putExtra(Constants.CARD, quizQuestions.get( index ));
		quizQuestionIntent.putExtra(Constants.STEP, ( index + 1) + "/" + quizQuestions.size() );
		this.index++;
		startActivityForResult( quizQuestionIntent, 1);		
	}
	
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		getMenuInflater().inflate(R.menu.context_action_menu, menu);
	}

	public boolean onContextItemSelected(MenuItem item) {
		final AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item
				.getMenuInfo();
		final ListView lv = (ListView) findViewById(R.id.card_list_view_main);
		final CardAdapter cardAdapter = (CardAdapter) lv.getAdapter();
		final Card card = cardAdapter.getItem(menuInfo.position);

		if (item.getItemId() == R.id.edit) {
			final Intent edit = new Intent(this, EditCardActivity.class);
			edit.putExtra(Constants.CARD, card);
			startActivityForResult(edit, 1);
		}
		if (item.getItemId() == R.id.stat) {
			final Intent stat = new Intent(this, ViewStatActivity.class);
			stat.putExtra(Constants.CARD_ID, card.getId());
			startActivityForResult(stat, 1);
		}
		if (item.getItemId() == R.id.delete) {
			card.setStat( getStat( card.getStatId() ));
			new AlertDialog.Builder(this)
					.setMessage("Do you really want to delete card?")
					.setCancelable(false)
					.setPositiveButton("Yes",
							new DialogInterface.OnClickListener() {

								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									deleteStat(card.getStat().getId());
									deleteCard(card.getId());
									setReloadData( true );
									updateListView();
								}
							}).setNegativeButton("No", null).show();
		}
		if( item.getItemId() == R.id.addNote ){
			final Intent stat = new Intent(this, AddNoteActivity.class);
			stat.putExtra(Constants.CARD_ID, card.getId());
			startActivityForResult(stat, 1);
		}
		if( item.getItemId() == R.id.viewNote ){
			final Intent stat = new Intent(this, ShowNotesActivity.class);
			stat.putExtra(Constants.CARD_ID, card.getId());
			startActivityForResult(stat, 1);
		}
		return super.onContextItemSelected(item);
	}
	
	@Override
	public void onBackPressed() {
		if( doubleBackToExitPressdOnce ){
			super.onBackPressed();
			return;
		}
		this.doubleBackToExitPressdOnce = true;
		Toast.makeText(this, "To exit click Back again", Toast.LENGTH_SHORT).show();
		
		new Handler().postDelayed(
			new Runnable() {
				
				@Override
				public void run() {
					doubleBackToExitPressdOnce = false;
				}
			}, 
			2000
		);
	}

	private CardAdapter getAdapter(CardDao cardDao){
		List<Card> cards = null;
		if( getReloadData() ){
			if( showWords && showPhrases ){
				cards = cardDao.getAll();
			}else{
				if( showWords || showPhrases ){
					if( showWords ){
						cards = cardDao.getCardsByType( "Word" );
					}
					if( showPhrases ){
						cards = cardDao.getCardsByType( "Phrase" );
					}
				}else{
					cards = new ArrayList<Card>();
				}
			}
			cardsList = cards;
			setReloadData( false );
		}
		final CardAdapter arrayAdapter = new CardAdapter(this,
				R.layout.listview_item_row, cardsList );
		return arrayAdapter;
	}
	
	private void updateListView() {
		final ListView lv = (ListView) findViewById(R.id.card_list_view_main);
		final CardDao cardDao = new CardDao(this);
		cardDao.open();
		final CardAdapter arrayAdapter = getAdapter(cardDao);
		lv.setAdapter(arrayAdapter);
		cardDao.close();
	}

	private void deleteStat(long id) {
		StatDao statDao = new StatDao(this);
		statDao.open();
		statDao.delete(id);
		statDao.close();
	}

	private void deleteCard(long id) {
		CardDao databaseAdapter = new CardDao(this);
		databaseAdapter.open();
		databaseAdapter.delete(id);
		databaseAdapter.close();
	}	
}
